package com.liangzong.betspider.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.liangzong.betspider.entity.TeamInfo;
import com.liangzong.betspider.entity.TeamPoint;
import com.liangzong.betspider.entity.TeamScore;
import com.liangzong.betspider.enums.TeamStateEnum;
import com.liangzong.betspider.enums.TeamTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.v106.network.Network;
import org.openqa.selenium.devtools.v106.network.model.WebSocketFrame;
import org.openqa.selenium.devtools.v106.network.model.WebSocketFrameReceived;
import org.openqa.selenium.devtools.v106.network.model.WebSocketFrameSent;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.remote.RemoteWebDriver;


import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static com.liangzong.betspider.utils.ProcessDataUtil.*;
import static com.liangzong.betspider.utils.ProcessDataUtil.str2obj;
import static com.liangzong.betspider.utils.SpiderInfoUtil.*;
import static com.liangzong.betspider.utils.SpiderInfoUtil.addPoint;

@Slf4j
public class WatchDataTask extends Thread {
    private String sessionId;
    WebDriver driver;
    int overTime;
    DevTools devTools;
    private boolean stoped;
    private volatile boolean stop;

    WatchDataTask(String sessionId, WebDriver driver, int overTime) {
        this.driver = driver;
        this.overTime = overTime;
        this.sessionId = sessionId;
    }

    public void stopWatchDataTask() {
        log.info("设置WatchDataTask 停止工作");
        this.stop = true;
        log.info("WatchDataTask 已结束工作");
    }

    @Override
    public void run() {
        while (!stop) {
            try {
                LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
                // https://www.365365304.com/#/IP/B1

                logEntries.forEach(entry -> {
                    String message = entry.getMessage();
                    JSONObject messageJSON = JSON.parseObject(message);
                    String method = messageJSON.getJSONObject("message").getString("method");
                    if (method.equalsIgnoreCase("Network.webSocketFrameSent")) {
                        log.info("发送msg: " + messageJSON.getJSONObject("message").getJSONObject("params").getJSONObject("response").getString("payloadData"));
                    } else if (method.equalsIgnoreCase("Network.webSocketFrameReceived")) {
                        String msg = messageJSON.getJSONObject("message").getJSONObject("params").getJSONObject("response").getString("payloadData");
                        parseMsg(overTime, sessionId, msg);
//                        log.info("收到msg" + msg.substring(0, 20) + " ...");
                    }
                });
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            pause(100);

        }
        stoped = true;
//        devTools = ((HasDevTools)driver).getDevTools();
//        devTools.createSession();
//        devTools.send(Network.enable(Optional.of(200), Optional.of(200), Optional.of(200)));
//        devTools.addListener(Network.webSocketFrameSent(), webSocketFrameSent -> printData(webSocketFrameSent));
//        devTools.addListener(Network.webSocketFrameReceived(), webSocketFrameReceived -> printData(webSocketFrameReceived, overTime, sessionId));
    }

    public boolean isStoped() {
        return stoped;
    }

    public static void printData(WebSocketFrameSent webSocketFrameSent) {
        WebSocketFrame response = webSocketFrameSent.getResponse();
        String msg = response.getPayloadData();
        log.info(msg);
    }

    public static void printData(WebSocketFrameReceived webSocketFrameReceived, int overTime, String sessionId) {
        WebSocketFrame response = webSocketFrameReceived.getResponse();
        String msg = response.getPayloadData();
        parseMsg(overTime, sessionId, msg);

    }

    private static void parseMsg(int overTime, String sessionId, String msg) {
        putSuccessfulTime(sessionId);
        char[] chars = msg.toCharArray();

        if (msg.indexOf("盘口编辑器") != -1) {
            getPoint(msg, overTime);
        }
        /*if (chars[0] == '' && chars[17] == '') {
            getScore(msg, overTime);
        }*/
        if (chars[0] == '\u0014' && chars[17] =='\u0001') {
            getScore(msg, overTime);
        }
        if (msg.indexOf("UC=全场") != -1) {
            gameOver(msg);
        }
        if (msg.indexOf("OVInPlay_10_0") != -1 && msg.indexOf("|CL;") != -1) {
            parseStart(msg);
        }
    }

    private static void gameOver(String msg) {
        String[] split = msg.split("\\|\b");
        for (String txt : split) {
            if (txt.indexOf("UC=全场") != -1) {
                String id = null;
                if (txt.indexOf("C1A_10_0") != -1) {
                    id = getStrByReg(txt, "OV(.*?)C1A_10_0");
                }
                if (id == null) {
                    continue;
                }
                log.info("全场 ：eventId=" + id + " #msg=" + txt);
                TeamInfo teamInfo = new TeamInfo();
                teamInfo.setId(id);
                teamInfo.setUpdateTime(LocalDateTime.now());
                teamInfo.setState(TeamStateEnum.GAMEOVER.getType());
                log.info("更新比赛状态为结束{}", id);
                addGameOverTeam(id, teamInfo);
            }
        }
    }

    //盘口
    private static void getPoint(String msg, int overTime) {
        String[] split = msg.split("\\|MG;");
        for (String s : split) {
            if (s.indexOf("=亚洲让分盘(") != -1) {

                List<TeamPoint> homeTeamPointList = new ArrayList<>();
                List<TeamPoint> awayTeamPointList = new ArrayList<>();
                String[] point = s.split("\\|MA;");
                if (point.length < 3) {
                    log.error("数据不符合要求或解析错误{}", msg);
                    return;
                }
                String s1 = point[0];
                String s2 = point[1];
                String s3 = point[2];
                //获取比赛ID
                String id = getStrByReg(s1, "IT=6V(\\d.*?)C1");
                LocalDateTime now = LocalDateTime.now();
                TeamInfo teamInfo = getTeamInfo(id);
                if (teamInfo == null) {
                    teamInfo = new TeamInfo();
                    teamInfo.setAddTime(now);
                    teamInfo.setState(TeamStateEnum.NORMAL.getType());
                    teamInfo.setRefresh_times(0);
                }
                teamInfo.setUpdateTime(now);
                //获取主队盘口
                String[] split2 = s2.split("\\|PA;");
                JSONObject homeJsonObject = str2obj(split2[0]);
                String homeTeamName = homeJsonObject.getString("NA");

                for (int i = 1; i < split2.length; i++) {
                    JSONObject teamPointInfo = str2obj(split2[i]);
                    TeamPoint teamPoint = new TeamPoint();
                    teamPoint.setTeamId(id);
                    teamPoint.setAddTime(now);
                    teamPoint.setTeamType(TeamTypeEnum.HOME.getType());
                    teamPoint.setHa(teamPointInfo.getString("HA"));
                    teamPoint.setOd(teamPointInfo.getString("OD"));
                    teamPoint.setOdds(transferOdds(teamPointInfo.getString("OD")));
                    teamPoint.setSort(teamPointInfo.getString("OR"));
                    teamPoint.setHd(teamPointInfo.getString("HD"));
                    homeTeamPointList.add(teamPoint);
                }

                //获取客队盘口
                String[] split3 = s3.split("\\|PA;");
                JSONObject awayJsonObject = str2obj(split3[0]);
                String awayTeamName = awayJsonObject.getString("NA");
                for (int i = 1; i < split3.length; i++) {
                    JSONObject teamPointInfo = str2obj(split3[i]);
                    TeamPoint teamPoint = new TeamPoint();
                    teamPoint.setTeamId(id);
                    teamPoint.setAddTime(now);
                    teamPoint.setTeamType(TeamTypeEnum.AWAY.getType());
                    teamPoint.setHa(teamPointInfo.getString("HA"));
                    teamPoint.setOd(teamPointInfo.getString("OD"));
                    teamPoint.setOdds(transferOdds(teamPointInfo.getString("OD")));
                    teamPoint.setSort(teamPointInfo.getString("OR"));
                    teamPoint.setHd(teamPointInfo.getString("HD"));
                    awayTeamPointList.add(teamPoint);
                }
                teamInfo.setUpdateTime(now);
                teamInfo.setId(id);
                teamInfo.setHomeTeamName(homeTeamName);
                teamInfo.setAwayTeamName(awayTeamName);
                teamInfo.setAwayTeamPointList(awayTeamPointList);
                teamInfo.setHomeTeamPointList(homeTeamPointList);

                addPoint(id, teamInfo, overTime);
            }
        }
    }

    //比分
    private static void getScore(String msg, int overTime) {

        String[] split = msg.split("\\|EV;");

        String url = getStrByReg(split[0], "(\\d.*?)M1_10");
        String s = split[1];

        //找出盘口 先用SG 分
        String[] split1 = s.split("\\|SG;");
        int index = 0;
        for (int i = 0; i < split1.length; i++) {
            if (split1[i].indexOf("CT=足球") != -1) {
                index = i;
                break;
            }
        }
        //然后用 TE
        String s2 = split1[index];
        String[] split3 = s2.split("\\|TE;");
        if (split3.length < 2) {
            log.error("解析错误[{}]", msg);
            return;
        }
        String s3 = split3[0];
        String s4 = split3[1];
        String s5 = split3[2];
        JSONObject jsonObject1 = str2obj(s3);
        //S1=射正球门;S2=射偏球门;S3=进攻;S4=危险进攻;S5=03:00#-1;S6=##-1;S7=球权％;
        JSONObject homeTeam = str2obj(s4);
        JSONObject awayTeam = str2obj(s5);
        String id = jsonObject1.getString("ID");
        LocalDateTime now = LocalDateTime.now();
        TeamInfo teamInfo = getTeamInfo(id);
        if (teamInfo == null) {
            teamInfo = new TeamInfo();
            teamInfo.setAddTime(now);
            teamInfo.setState(TeamStateEnum.NORMAL.getType());
            teamInfo.setRefresh_times(0);
        }
        teamInfo.setUpdateTime(now);
        teamInfo.setUrl(url);
        String timeInfo = getTimeInfo(url);
        teamInfo.setTime(timeInfo);
        TeamScore homeTeamScore = new TeamScore();
        homeTeamScore.setTeamType(TeamTypeEnum.HOME.getType());
        homeTeamScore.setTeamId(id);
        homeTeamScore.setAddTime(now);
        TeamScore awayTeamScore = new TeamScore();
        awayTeamScore.setTeamType(TeamTypeEnum.AWAY.getType());
        awayTeamScore.setTeamId(id);
        awayTeamScore.setAddTime(now);
        teamInfo.setHomeTeamScore(homeTeamScore);
        teamInfo.setAwayTeamScore(awayTeamScore);

        if (!homeTeam.isEmpty() && !awayTeam.isEmpty()) {
            if (homeTeam.getInteger("OR") != null) {
                homeTeamScore.setSort(homeTeam.getInteger("OR"));
            }
            homeTeamScore.setS1(homeTeam.getInteger("S1") != null ? homeTeam.getInteger("S1") : 0);
            homeTeamScore.setS2(homeTeam.getInteger("S2") != null ? homeTeam.getInteger("S2") : 0);
            homeTeamScore.setS3(homeTeam.getInteger("S3") != null ? homeTeam.getInteger("S3") : 0);
            homeTeamScore.setS4(homeTeam.getInteger("S4") != null ? homeTeam.getInteger("S4") : 0);
            homeTeamScore.setS5(homeTeam.getInteger("S5") != null ? homeTeam.getInteger("S5") : 0);
            homeTeamScore.setS6(homeTeam.getInteger("S6") != null ? homeTeam.getInteger("S6") : 0);
            homeTeamScore.setS7(homeTeam.getInteger("S7") != null ? homeTeam.getInteger("S7") : 0);
            homeTeamScore.setSc(homeTeam.getInteger("SC") != null ? homeTeam.getInteger("SC") : 0);

            awayTeamScore.setS1(awayTeam.getInteger("S1") != null ? awayTeam.getInteger("S1") : 0);
            awayTeamScore.setS2(awayTeam.getInteger("S2") != null ? awayTeam.getInteger("S2") : 0);
            awayTeamScore.setS3(awayTeam.getInteger("S3") != null ? awayTeam.getInteger("S3") : 0);
            awayTeamScore.setS4(awayTeam.getInteger("S4") != null ? awayTeam.getInteger("S4") : 0);
            awayTeamScore.setS5(awayTeam.getInteger("S5") != null ? awayTeam.getInteger("S5") : 0);
            awayTeamScore.setS6(awayTeam.getInteger("S6") != null ? awayTeam.getInteger("S6") : 0);
            awayTeamScore.setS7(awayTeam.getInteger("S7") != null ? awayTeam.getInteger("S7") : 0);
            awayTeamScore.setSc(awayTeam.getInteger("SC") != null ? awayTeam.getInteger("SC") : 0);
        }
        addPoint(id, teamInfo, overTime);
//            System.out.println("ID:" + id + "#-->url=" + url);
//            System.out.println("ID:" + id + "#-->awayTeam=" + homeTeam);
//            System.out.println("ID:" + id + "#-->awayTeam=" + awayTeam);


    }

    public static void parseStart(String msg) {
        String[] split = msg.split("\\|CL;");

        if (split.length >= 2) {
            for (String s : split) {
                if (s.indexOf("ID=1;") != -1 && s.indexOf("CD=1;") != -1) {
                    System.out.println("足球");
                } else if (s.indexOf("ID=18;") != -1) {
                    System.out.println("篮球");
                } else {
                    continue;
                }

                String[] competitions = s.split("\\|CT;");
                if (competitions.length > 0) {
                    for (int i = 1; i < competitions.length; i++) {
                        System.out.println(competitions[i]);
                        String comp = competitions[i];
                        String[] data = comp.split("\\|EV;");
                        String datum = data[0];

                        JSONObject compObject = str2obj(datum);
                        String league = compObject.getString("NA");

                        for (int j = 1; j < data.length; j++) {
                            String datum1 = data[j];
                            String[] split1 = datum1.split("\\|MA;");
                            JSONObject jsonObject = str2obj(split1[0]);
                            String id = jsonObject.getString("ID");
                            String na = jsonObject.getString("NA");
                            if (id.indexOf("C1A_10_0") != -1 && na.indexOf(" v ") != -1) {

                                String eventId = id.substring(0, 9);
                                String score = jsonObject.getString("SS");
                                String vsTeams = jsonObject.getString("NA");
                                String[] splitTeam = vsTeams.split(" v ");
                                String hometeam = splitTeam[0];
                                String awayteam = splitTeam[1];
                                String PA0 = datum1.split("\\|PA;")[0];
                                JSONObject PA0Json = str2obj(PA0);
                                String TU = PA0Json.getString("TU");
                                Integer  TT = PA0Json.getInteger("TT");
                                Integer TS = PA0Json.getInteger("TS");
                                Integer TM = PA0Json.getInteger("TM");
                                String retimeset;
                                if (TM == 0 && TT == 0) {
                                    retimeset = "00:00";
                                } else {
                                    if (TT == 1) {
                                        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
                                        LocalDateTime begin = LocalDateTime.parse(TU, df);
                                        LocalDateTime now = LocalDateTime.now(ZoneId.of("UTC"));
                                        Duration between = Duration.between(now, begin);
                                        long minutes = between.toMinutes();
                                        long seconds = between.toSeconds();
                                        retimeset = sec2min(seconds);
                                    } else {
                                        retimeset = "45:00";
                                    }
                                }
                                System.out.println(String.format("开始：league=%s, hometeam=%s, awayteam=%s, score=%s, restimeset=%s eventId=%s", league, hometeam, awayteam, score, retimeset, eventId));
                            }
                        }
                    }
                }
            }
        }
    }


    public static String sec2min(long secs) {
        String mSec;
        String mMin;
        // 秒数
        long sec = secs % 60;
        // 分钟数
        long min = (secs - sec) / 60;
        // 如果秒数没超过10就在他前面加个0
        if (sec < 10) {
            mSec = "0" + sec;
        } else {
            mSec = String.valueOf(sec);
        }
        // 如果分钟数没超过10就在他前面加个0
        if (min < 10) {
            mMin = "0" + min;
        } else {
            mMin = String.valueOf(min);
        }
        // 打印最终的结果
        return mMin + ":" + mSec;
    }

    private static void pause() {
        pause(3000);
    }

    private static void pause(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            log.error(e.getMessage(), e);
        }
    }
}

